package com.lvy.hczn.front.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lvy.hczn.front.business.service.*;
import com.lvy.hczn.front.common.constant.Constants;
import com.lvy.hczn.front.common.constant.MqConstants;
import com.lvy.hczn.front.common.core.domain.entity.SysDictData;
import com.lvy.hczn.front.common.core.domain.entity.SysDictType;
import com.lvy.hczn.front.common.core.domain.entity.SysUser;
import com.lvy.hczn.front.common.exception.UtilException;
import com.lvy.hczn.front.common.utils.DictUtils;
import com.lvy.hczn.front.system.domain.business.*;
import com.lvy.hczn.front.system.domain.business.dto.ParcelDataDto;
import com.lvy.hczn.front.system.domain.system.dto.SysDictTypeDto;
import com.lvy.hczn.front.system.mapper.SysDictDataMapper;
import com.lvy.hczn.front.system.mapper.SysDictTypeMapper;
import com.lvy.hczn.front.system.service.*;
import com.lvy.hczn.mq.rocket.ParamInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class ConsumeServiceImpl implements ConsumeService {

    /*@Autowired
    private PurchaseSheetService purchaseSheetService;

    @Autowired
    private PurchaseSheetDetailService purchaseSheetDetailService;

    @Autowired
    private PickUpDetailService pickUpDetailService;

    @Autowired
    private StockInService stockInService;*/

    @Autowired
    private TemperatureZoneService temperatureZoneService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    @Autowired
    private SysDictTypeMapper sysDictTypeMapper;

    @Autowired
    private WarehouseService warehouseService;

    @Autowired
    private AccessManagerService accessManagerService;

    @Autowired
    private GoodsBoxSpecService goodsBoxSpecService;

    @Autowired
    private DeliveryOrderDetailService deliveryOrderDetailService;

    @Autowired
    private PurchaseOrderService purchaseOrderService;

    @Autowired
    private PurchaseOrderDetailService purchaseOrderDetailService;

    @Autowired
    private DeliveryOrderService deliveryOrderService;

    @Autowired
    private SaleOrderService saleOrderService;

    @Autowired
    private SaleOrderDetailService saleOrderDetailService;

    @Autowired
    private SpuService spuService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private BillOfParcelsService billOfParcelsService;

    @Autowired
    private BillOfParcelsDetailService billOfParcelsDetailService;

    @Autowired
    private ISysUserService sysUserService;

    @Autowired
    private WarehousingEntryService warehousingEntryService;

    @Autowired
    private GoodsBoxService goodsBoxService;

    @Autowired
    private PackSpecService packSpecService;

    @Autowired
    private PackSpuService packSpuService;

    @Autowired
    private PackService packService;

    @Autowired
    private TransferOrderService transferOrderService;

    @Autowired
    private TransferOrderDetailService transferOrderDetailService;

    @Autowired
    private SortTaskService sortTaskService;

    @Autowired
    private TransportService transportService;

    @Autowired
    private OutboundOrderService outboundOrderService;

    @Autowired
    private SpuSortRecordService spuSortRecordService;

    @Autowired
    private SortTaskDetailService sortTaskDetailService;

    @Autowired
    private IProductionProcessingTypeService productionProcessingTypeService;

    @Autowired
    private IParcelService parcelService;

    /**
     * 同步表的消息消费业务处理
     *
     * @param message
     * @return
     * @author yw
     * @date 2021-06-28 12:27:12
     */
    @Override
    public void doBusiness(MessageExt message) throws Exception {
        String tag = message.getProperties().get("TAGS");
        String key = message.getProperties().get("KEYS");
        byte[] bt = message.getBody();
        String str = new String(bt, StandardCharsets.UTF_8);
        String topic = message.getTopic();

        log.error("str>{}", str);
        log.error("topic->{}", topic);
        log.error("tag->{}", tag);
        if (topic.equals(MqConstants.TOPIC_SYNC_SPU)) {
            syncSpu(str, message);
        } else if (topic.equals(MqConstants.TOPIC_SYNC_SKU)) {
            syncSkuFromTransmit(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_SYNC_CATEGORY)) {
            syncCategory(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_TEMPER_AREA_CONFIG)) {
            syncTemperatureZone(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_DICT)) {
            syncDict(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_WAREHOUSE_GOODS_SPEN)) {
            syncGoodsSpec(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_PACK_SPEC)) {
            syncPackSpecFromTransmit(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_BAG)) {
            goodsBag(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_PACK)) {
            pack(topic, tag, key, str);
        } else if (topic.equals(MqConstants.TOPIC_PRODUCTION_PROCESSING_TYPE)) {
            productionProcessingType(topic, tag, key, str);
        } else {
            //topic绑定运营区域，tag为仓库编号
            regionArea(topic, tag, key, str);
        }
    }

    /**
     * 生产加工方式同步
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-07-18 16:51:11
     */
    public void productionProcessingType(String topic, String tag, String key, String str) {
        log.error("同步加工方式到仓库:{}", str);
        ParamInfo info = JSON.parseObject(str, ParamInfo.class);
        if (info != null && info.getList() != null && !info.getList().isEmpty()) {
            List<ProductionProcessingType> list = JSON.parseArray(JSON.toJSONString(info.getList()), ProductionProcessingType.class);
            list.forEach(item -> {
                ProductionProcessingType productionProcessingType = productionProcessingTypeService.getById(item.getId());
                if (productionProcessingType != null) {
                    item.setId(productionProcessingType.getId());
                    productionProcessingTypeService.updateById(item);
                } else {
                    productionProcessingTypeService.save(item);
                }
            });
        }
    }

    /**
     * 同步包装袋到仓库
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-07-18 16:51:11
     */
    public void pack(String topic, String tag, String key, String str) {
        log.error("同步包装袋到仓库:{}", str);
        ParamInfo<Pack> info = JSONUtil.toBean(str, ParamInfo.class);
        if (info != null && info.getList() != null && !info.getList().isEmpty()) {
            List<Pack> list = JSONUtil.toList(JSONUtil.toJsonStr(info.getList()), Pack.class);
            list.forEach(item -> {
                if (item.getDelFlag() != null && item.getDelFlag().equals(Constants.DEL_FLAG_INVALID)) {
                    packService.removeById(item.getId());
                } else {
                    packService.saveOrUpdate(item);
                }
            });
        }
    }

    /**
     * 商品绑定包装袋
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-07-18 15:52:59
     */
    public void goodsBag(String topic, String tag, String key, String str) {
        log.error("商品绑定包装袋:{}", str);
        ParamInfo<PackSpec> info = JSONUtil.toBean(str, ParamInfo.class);
        if (info != null && info.getList() != null && !info.getList().isEmpty()) {
            List<PackSpu> list = JSONUtil.toList(JSONUtil.toJsonStr(info.getList()), PackSpu.class);
            list.forEach(item -> {
                if (item.getDelFlag() != null && item.getDelFlag().equals(Constants.DEL_FLAG_INVALID)) {
                    packSpuService.removeById(item.getId());
                } else {
                    packSpuService.saveOrUpdate(item);
                }
            });
        }
    }

    /**
     * 总仓供应商分拣加工打包信息
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-07-09 14:18:14
     */
    public void syncPackSpecFromTransmit(String topic, String tag, String key, String str) {
        log.error("总仓供应商分拣加工打包信息:{}", str);
        ParamInfo<PackSpec> info = JSONUtil.toBean(str, ParamInfo.class);
        if (info.getData() != null) {
            PackSpec packSpec = JSONUtil.toBean(JSONUtil.toJsonStr(info.getData()), PackSpec.class);
            packSpecService.saveOrUpdateInfo(packSpec, false);
        }
    }

    /**
     * 从数据转发中心获取sku
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-05 16:11:25
     */
    public void syncSkuFromTransmit(String topic, String tag, String key, String str) {
        log.error("从数据转发中心获取sku:{}", str);
        ParamInfo<Sku> info = JSONUtil.toBean(str, ParamInfo.class);
        if (info.getList() != null && !info.getList().isEmpty()) {
            List<Sku> list = JSONUtil.toList(JSONUtil.toJsonStr(info.getList()), Sku.class);
            list.forEach(item -> {
                item.setId(item.getBarcodeId());
                skuService.saveOrUpdateSku(item);
            });
        } else if (info.getData() != null) {
            Sku sku = JSONUtil.toBean(JSONUtil.toJsonStr(info.getData()), Sku.class);
            sku.setId(sku.getBarcodeId());
            skuService.saveOrUpdateSku(sku);
        }
    }

    /**
     * 同步货箱规格信息
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-05-25 11:29:20
     */
    public void syncGoodsSpec(String topic, String tag, String key, String str) {
        log.error("同步货箱规格信息:{}", str);
        ParamInfo<GoodsBoxSpec> info = JSONUtil.toBean(str, ParamInfo.class);
        if (info.getData() != null) {
            GoodsBoxSpec goodsBoxSpec = JSONUtil.toBean(JSONUtil.toJsonStr(info.getData()), GoodsBoxSpec.class);
            goodsBoxSpecService.saveOrUpdate(goodsBoxSpec);
        } else if (info.getData() != null && !info.getList().isEmpty()) {
            List<GoodsBoxSpec> list = JSONUtil.toList(JSONUtil.toJsonStr(info.getList()), GoodsBoxSpec.class);
            goodsBoxSpecService.saveOrUpdateBatch(list);
        }
    }

    /**
     * topic绑定运营区域，tag为仓库编号
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-05-24 11:21:52
     */
    public void regionArea(String topic, String tag, String key, String str) {

        Warehouse warehouse = warehouseService.selectLocalWarehouseFront();
        //货箱租赁
        String boxLeaseTag = "";
        //修改仓库信息
        String warehouseTag = "";
        String areaTopic = MqConstants.TOPIC_WAREHOUSE_AREA + "_";
        if (warehouse != null) {
            //前置仓运营区域tag
            boxLeaseTag = warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_LEASE;
            areaTopic = areaTopic + warehouse.getAreaCode().replace(".", "");
            warehouseTag = warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_FROM_TRANSMIT_TAG;
        }

        if (topic.equals(areaTopic)) {
            if (boxLeaseTag.equals(tag)) {
                //货箱租赁单生成门禁
                boxLeaseAccess(topic, tag, key, str);
            } else if (warehouseTag.equals(tag)) {
                //修改仓库信息
                log.info("仓库信息修改：{}", str);
                updateWarehouse(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_PURCHASE_ENTRY).equals(tag)) {
                //配送/运输单同步
                initWarehouseOrder(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_DELIVERY_ENTRY).equals(tag)) {
                //仓库取货单初始化
                initDelivery(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_ENTRY).equals(tag)) {
                //仓库入库单初始化
                initWarehouseEntry(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_DELIVERY_SALE).equals(tag)) {
                //销售配送
                syncSaleOrderFromTransmit(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_DELIVERY_SELF_TAG).equals(tag)) {
                //供应商自配到仓库tag
                syncBillOfParcelsFromTransmit(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_SORTER_USER).equals(tag)) {
                //分拣员同步
                initSorterFromTransmit(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_WAREHOUSE_CIRCULATION_BOX).equals(tag)) {
                //调拨/配送入库货箱先在仓库初始化
                initGoodsBoxFromTransmit(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_TRANSFER).equals(tag)) {
                initTransferAndDetail(topic, tag, key, str, warehouse);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_TRANSPORT_TAG).equals(tag)) {
                initTransportAndDetail(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_TRANSPORT_TAG_OUT).equals(tag)) {
                initTransportOutboundAndDetail(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_CREDIT_NOTE_TAG).equals(tag)) {
                initCreditNote(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_FRM_LOSS_TAG).equals(tag)) {
                initFrmLoss(topic, tag, key, str);
            } else if ((warehouse.getWarehouseCode() + "_" + MqConstants.TOPIC_SYNC_PARCEL).equals(tag)) {
                syncParcel(topic, tag, key, str);
            }
        }
    }

    /**
     * 平台临期商品推送
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-08-26 20:36:34
     */
    public void initFrmLoss(String topic, String tag, String key, String str) {
        ParamInfo info = JSON.parseObject(str, ParamInfo.class);
        if (info.getList() != null) {
            List<SpuSortRecord> spuSortRecordList = JSON.parseArray(JSON.toJSONString(info.getList()), SpuSortRecord.class);
            spuSortRecordList.forEach(spuSortRecord -> {
                SpuSortRecord record = spuSortRecordService.getOne(Wrappers.<SpuSortRecord>lambdaQuery().eq(SpuSortRecord::getRecodeCode, spuSortRecord.getRecodeCode()));
                if (record != null) {
                   /* spuSortRecord.setId(record.getId());
                    spuSortRecordService.updateById(spuSortRecord);*/
                } else {
                    spuSortRecordService.save(spuSortRecord);
                }
            });
        }
    }

    /**
     * 销售退货单接收（还未配送出库）
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-08-26 20:36:34
     */
    @Transactional
    public synchronized void initCreditNote(String topic, String tag, String key, String str) {
        ParamInfo<SaleOrder> info = JSON.parseObject(str, ParamInfo.class);
        if (info.getData() != null) {
            SaleOrder saleOrder = JSON.parseObject(JSON.toJSONString(info.getData()), SaleOrder.class);
            SaleOrder model = saleOrderService.getOne(Wrappers.<SaleOrder>lambdaQuery().eq(SaleOrder::getSourceId, saleOrder.getSourceId()).eq(SaleOrder::getType, com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_TYPE_TWO));
            boolean sorting = true;
            //下单时，仓库整个单的商品库存全部报损
            boolean frmLossALL = false;
            /*退货订单处理需分步骤处理，场景较多，待分拣时的处理，分拣中的处理，分拣过程整体缺货的处理**/
            if (saleOrder.isReturnOfGoods()) {
                //商品退货，且还未触发分拣任务时，不分拣，根据sorting置退货单为已完成
                SaleOrder saleOrderSale = saleOrderService.getOne(Wrappers.<SaleOrder>lambdaQuery().eq(SaleOrder::getSaleOrderCode, saleOrder.getSaleOrderCode()).eq(SaleOrder::getType, Constants.SALE_ORDER_TYPE_ONE).eq(SaleOrder::getStatus, com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_STATUS_ZERO));
                if (saleOrderSale != null) {
                    sorting = false;
                } else {
                    if (saleOrder.getList() != null && !saleOrder.getList().isEmpty()) {
                        //分拣中，则sort还是为true，分拣中的订单退货，不能更改成已完成，需要退货入库，单没有订单没在分拣中的时候，再考虑整体缺货的场景
                        SaleOrder saleOrderSaleIng = saleOrderService.getOne(Wrappers.<SaleOrder>lambdaQuery().eq(SaleOrder::getSaleOrderCode, saleOrder.getSaleOrderCode()).eq(SaleOrder::getType, Constants.SALE_ORDER_TYPE_ONE).eq(SaleOrder::getStatus, com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_STATUS_ONE));
                        if (saleOrderSaleIng == null) {
                            //查询销售分拣出库单据，当整体缺货的时候，不会生成入库单，然后整体缺货的时候，平台会推送订单取消，然后直接过滤掉
                            WarehousingEntry entry = warehousingEntryService.selectBySaleOrder(com.lvy.hczn.front.common.constant.Constants.WAREHOUSING_ENTRY_DATA_TYPE_EIGHT, saleOrder, saleOrder.getList().get(0));
                            if (entry == null) {
                                sorting = false;
                                frmLossALL = true;
                                saleOrder.setRemark("分拣时全部报损的取消订单");
                            }
                        }
                    }
                }

            }
            if (model != null) {
                saleOrder.setId(model.getId());
                saleOrderService.updateById(saleOrder);
            } else {
                saleOrderService.save(saleOrder);
            }
            for (SaleOrderDetail saleOrderDetail : saleOrder.getList()) {
                SaleOrderDetail modelDetail = saleOrderDetailService.getOne(Wrappers.<SaleOrderDetail>lambdaQuery().eq(SaleOrderDetail::getSourceId, saleOrderDetail.getSourceId()));
                if (modelDetail != null) {
                    saleOrderDetail.setId(modelDetail.getId());
                    saleOrderDetailService.updateById(saleOrderDetail);
                } else {
                    //商品退货，且还未触发分拣任务时，不分拣，根据sorting置退货单为已完成
                    if (saleOrder.isReturnOfGoods() && !sorting) {
                        saleOrderDetail.setStatus(Constants.SALE_ORDER_DETAIL_STATUS_SIX);
                        String dataType = com.lvy.hczn.front.common.constant.Constants.WAREHOUSING_ENTRY_DATA_TYPE_EIGHT;
                        String status = com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_STATUS_ZERO;
                        //更新销售单状态
                        SaleOrderDetail saleOrderDetailInfo = saleOrderDetailService.getOne(Wrappers.<SaleOrderDetail>lambdaQuery().eq(SaleOrderDetail::getSaleOrderCode, saleOrder.getSaleOrderCode()).eq(SaleOrderDetail::getDataType, dataType).eq(SaleOrderDetail::getStatus, status).eq(SaleOrderDetail::getSpuId, saleOrderDetail.getSpuId()).eq(SaleOrderDetail::getSkuCode, saleOrderDetail.getSkuCode()));
                        if (saleOrderDetailInfo != null) {
                            saleOrderDetailInfo.setStatus(com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_DETAIL_STATUS_SIX);
                            saleOrderDetailService.updateById(saleOrderDetailInfo);
                        }
                    }
                    saleOrderDetailService.save(saleOrderDetail);
                }
            }

            //品退货，且还未触发分拣任务时，不分拣，根据sorting置退货单为已完成,且同送库存到平台
            if (saleOrder.isReturnOfGoods() && !sorting) {
                Integer outStock = com.lvy.hczn.front.common.constant.Constants.OUT_STOCK_ZERO;
                //如果是整单报损的缺货，则不记录入库单和分拣单，因为已经分拣过了
                if (!frmLossALL && outStock.equals(saleOrder.getOutStock())) {
                    ThreadUtil.execAsync(() -> {
                        /**未分拣退货，直接生成FHCK和TDRK单据更新到平台库存
                         * 且虚拟生成已完成的分拣任务（或许可以不生成，先这样），平台那边没有直接更新库存**/
                        List<WarehousingEntry> list = new ArrayList<>();
                        saleOrderService.initCreditNoteWarehousingEntry(saleOrder, list);
                        if (!list.isEmpty() && warehousingEntryService.saveBatch(list)) {
                            List<SaleOrder> saleOrderList = new ArrayList<>();
                            saleOrderList.add(saleOrder);
                            sortTaskService.generateSortTask(saleOrderList, true);
                        }
                    });
                }
            }
        }
    }

    /**
     * 运输单信息保存
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-08-26 20:36:34
     */
    public void initTransportAndDetail(String topic, String tag, String key, String str) {
        ParamInfo<Transport> info = JSON.parseObject(str, ParamInfo.class);
        if (info.getData() != null) {
            Transport transport = JSON.parseObject(JSON.toJSONString(info.getData()), Transport.class);
            transportService.syncFromTransmit(transport);
        }
    }

    /**
     * 运输单仓库出库信息保存
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-08-26 20:36:34
     */
    public void initTransportOutboundAndDetail(String topic, String tag, String key, String str) {
        ParamInfo<OutboundOrder> info = JSON.parseObject(str, ParamInfo.class);
        if (info.getData() != null) {
            OutboundOrder outboundOrder = JSON.parseObject(JSON.toJSONString(info.getData()), OutboundOrder.class);
            outboundOrderService.syncOutboundOrderFromTransmit(outboundOrder);
        }
    }

    /**
     * 调拨及详情同步到仓库
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-25 21:15:14
     */
    public void initTransferAndDetail(String topic, String tag, String key, String str, Warehouse warehouse) {
        log.error("initTransferAndDetail调拨信息：{}", str);
        ParamInfo<TransferOrder> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        List<TransferOrder> list = JSONUtil.toList(JSONUtil.toJsonStr(paramInfo.getList()), TransferOrder.class);
        if (list != null && !list.isEmpty()) {
            list.forEach(transferOrder -> {
                //第一次调拨，生成调拨分拣任务
                TransferOrder model = transferOrderService.getById(transferOrder.getId());
                if (model == null) {
                    //不直接生成，定时生成分拣任务
                    /*if (transferOrderService.save(transferOrder)) {
                        List<TransferOrder> transferOrders = new ArrayList<>();
                        transferOrders.add(transferOrder);
                        sortTaskService.generateSortTaskByTransfer(transferOrders);
                    }*/
                    transferOrder.setAssociationRepId(warehouse.getWarehouseCode());
                    transferOrderService.save(transferOrder);
                } else {
                    transferOrderService.updateById(transferOrder);
                }
                if (transferOrder.getDetailList() != null && !transferOrder.getDetailList().isEmpty()) {
                    List<TransferOrderDetail> transferDetailList = JSONUtil.toList(JSONUtil.toJsonStr(transferOrder.getDetailList()), TransferOrderDetail.class);
                    transferOrderDetailService.saveOrUpdateBatch(transferDetailList);
                }
            });
        }
    }

    /**
     * 配送入库货箱先在仓库初始化
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-25 21:15:14
     */
    public void initGoodsBoxFromTransmit(String topic, String tag, String key, String str) {
        log.error("initGoodsBoxFromTransmit货箱信息：{}", str);
        ParamInfo<GoodsBox> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        List<GoodsBox> list = JSONUtil.toList(JSONUtil.toJsonStr(paramInfo.getList()), GoodsBox.class);
        if (list != null && !list.isEmpty()) {
            Warehouse warehouse = warehouseService.selectLocalWarehouseFront();
            list.stream().forEach(item -> {
                item.setWarehouseId(warehouse.getId());
                GoodsBox goodsBox = goodsBoxService.getOne(Wrappers.<GoodsBox>lambdaQuery().eq(GoodsBox::getBoxCode, item.getBoxCode()));
                if (goodsBox != null) {
                    //采购入库：已入库，入库中，异常状态的货箱，不做更改
                    if (!com.lvy.hczn.front.business.common.Constants.GOODS_BOX_STATE_ZERO.equals(goodsBox.getStatus()) && !com.lvy.hczn.front.business.common.Constants.GOODS_BOX_STATE_THREE.equals(goodsBox.getStatus()) && !com.lvy.hczn.front.business.common.Constants.GOODS_BOX_STATE_FOUR.equals(goodsBox.getStatus())) {
                        item.setId(goodsBox.getId());
                        goodsBoxService.updateById(item);
                    }
                } else {
                    goodsBoxService.save(item);
                }
            });
        }
    }

    /**
     * 仓库入库单
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-20 21:09:07
     */
    public void initWarehouseEntry(String topic, String tag, String key, String str) {
        log.error("initWarehouseEntry入库单：{}", str);
        ParamInfo<WarehousingEntry> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        List<WarehousingEntry> list = JSONUtil.toList(JSONUtil.toJsonStr(paramInfo.getList()), WarehousingEntry.class);
        if (list != null && !list.isEmpty()) {
            list.forEach(item -> {
                WarehousingEntry entry = warehousingEntryService.getOne(Wrappers.<WarehousingEntry>lambdaQuery().eq(WarehousingEntry::getServiceCode, item.getServiceCode()).eq(WarehousingEntry::getSourceId, item.getSourceId()));
                //在数据中心取值的时候，spuId赋值为spuCode，所以查询条件为spuId，暂时不调整
                Spu spu = spuService.getOne(Wrappers.<Spu>lambdaQuery().eq(Spu::getSpuCode, item.getSpuId()).likeLeft(Spu::getSourceId, Constants.SOURCE_ID_DEFAULT + item.getSpuId()));
                if (spu == null) {
                    log.error("入库单接收异常，商品为空:{}", str);
                    throw new UtilException("商品为空");
                }
                item.setSpuId(spu.getId());
                if (entry != null) {
                    if (com.lvy.hczn.front.business.common.Constants.ENTRY_ING.equals(entry.getStatus())) {
                        item.setId(entry.getId());
                        warehousingEntryService.updateById(item);
                    }
                } else {
                    warehousingEntryService.save(item);
                }
            });
        }
    }

    /**
     * 仓库取货单
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-20 21:01:38
     */
    public void initDelivery(String topic, String tag, String key, String str) {
        log.error("initDelivery仓库取货单：{}", str);
        ParamInfo<DeliveryOrder> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        DeliveryOrder deliveryOrder = JSONUtil.toBean(JSONUtil.toJsonStr(paramInfo.getData()), DeliveryOrder.class);
        DeliveryOrder deliveryOrderInfo = deliveryOrderService.getOne(Wrappers.<DeliveryOrder>lambdaQuery().eq(DeliveryOrder::getDeliveryOrderCode, deliveryOrder.getDeliveryOrderCode()).eq(DeliveryOrder::getSourceId, deliveryOrder.getSourceId()));
        if (deliveryOrderInfo != null) {
            deliveryOrder.setId(deliveryOrderInfo.getId());
            deliveryOrderService.updateById(deliveryOrder);
        } else {
            deliveryOrderService.save(deliveryOrder);
        }
        if (deliveryOrder.getList() != null && !deliveryOrder.getList().isEmpty()) {
            for (DeliveryOrderDetail detail : deliveryOrder.getList()) {
                DeliveryOrderDetail model = deliveryOrderDetailService.getOne(Wrappers.<DeliveryOrderDetail>lambdaQuery().eq(DeliveryOrderDetail::getDeliveryOrderCode, deliveryOrder.getDeliveryOrderCode()).eq(DeliveryOrderDetail::getSourceId, detail.getSourceId()));
                if (model != null) {
                    detail.setId(model.getId());
                    deliveryOrderDetailService.updateById(detail);
                } else {
                    deliveryOrderDetailService.save(detail);
                }
            }
        }
    }

    /**
     * 同步仓库值班分拣员信息
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-11 15:35:20
     */
    public void initSorterFromTransmit(String topic, String tag, String key, String str) {
        ParamInfo<SysUser> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        List<SysUser> list = JSONUtil.toList(JSONUtil.toJsonStr(paramInfo.getList()), SysUser.class);
        list.forEach(sysUser -> {
            SysUser user = sysUserService.selectUserByEmail(sysUser.getEmail());
            if (user != null) {
                sysUser.setUserId(user.getUserId());
                sysUserService.updateUserInfo(sysUser);
            } else {
                sysUserService.initPostRole(sysUser);
                sysUser.setUserId(null);
                sysUserService.insertUser(sysUser);
            }
        });
    }

    /**
     * 从数据转发中心同步配送单，暂时时自配，平台配送会走配送单或者运输单
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-07 15:13:56
     */
    public void syncBillOfParcelsFromTransmit(String topic, String tag, String key, String str) {
        ParamInfo<BillOfParcels> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        BillOfParcels billOfParcels = JSONUtil.toBean(JSONUtil.toJsonStr(paramInfo.getData()), BillOfParcels.class);
        BillOfParcels billOfParcelsModel = billOfParcelsService.getOne(Wrappers.<BillOfParcels>lambdaQuery().eq(BillOfParcels::getSourceId, billOfParcels.getSourceId()).last("limit 1"));
        if (billOfParcelsModel != null) {
            billOfParcels.setId(billOfParcelsModel.getId());
            billOfParcelsService.updateById(billOfParcels);
        } else {
            billOfParcelsService.save(billOfParcels);
        }
        List<BillOfParcelsDetail> list = JSONUtil.toList(JSONUtil.toJsonStr(billOfParcels.getList()), BillOfParcelsDetail.class);
        list.forEach(item -> {
            BillOfParcelsDetail detail = billOfParcelsDetailService.getOne(Wrappers.<BillOfParcelsDetail>lambdaQuery().eq(BillOfParcelsDetail::getSourceId, item.getSourceId()).last("limit 1"));
            Spu spu = spuService.getOne(Wrappers.<Spu>lambdaQuery().eq(Spu::getSpuCode, item.getProductSysCode()).likeLeft(Spu::getSourceId, Constants.SOURCE_ID_DEFAULT + item.getProductSysCode()));
            if (spu == null) {
                log.error("供应商自配异常,商品为空：{}", str);
                throw new UtilException("商品为空");
            }
            item.setSpuId(spu.getId());
            if (detail != null) {
                item.setId(detail.getId());
                billOfParcelsDetailService.updateById(item);
            } else {
                billOfParcelsDetailService.save(item);
            }
        });
    }

    /**
     * 销售订单从数据转发中心同步
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-04 16:38:53
     */
    @Transactional
    public void syncSaleOrderFromTransmit(String topic, String tag, String key, String str) {
        log.error("syncSaleOrderFromTransmit销售配送单：{}", str);
        ParamInfo<PurchaseOrder> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        SaleOrder saleOrder = JSONUtil.toBean(JSONUtil.toJsonStr(paramInfo.getData()), SaleOrder.class);
        SaleOrder saleOrderInfo = saleOrderService.getOne(Wrappers.<SaleOrder>lambdaQuery().eq(SaleOrder::getSaleOrderCode, saleOrder.getSaleOrderCode()).eq(SaleOrder::getSourceId, saleOrder.getSourceId()));
        if (saleOrderInfo != null) {
            saleOrder.setId(saleOrderInfo.getId());
            saleOrderService.updateById(saleOrder);
        } else {
//            saleOrder.setStatus(Constants.SALE_ORDER_STATUS_ZERO);
            saleOrderService.save(saleOrder);
        }
        if (saleOrder.getList() != null && !saleOrder.getList().isEmpty()) {
            List<SaleOrderDetail> list = JSONUtil.toList(JSONUtil.toJsonStr(saleOrder.getList()), SaleOrderDetail.class);
            for (SaleOrderDetail detail : list) {
                SaleOrderDetail saleOrderDetail = saleOrderDetailService.getOne(Wrappers.<SaleOrderDetail>lambdaQuery().eq(SaleOrderDetail::getSaleOrderCode, saleOrder.getSaleOrderCode()).eq(SaleOrderDetail::getSourceId, detail.getSourceId()).last("limit 1"));
                //在数据中心取值的时候，spuId赋值为spuCode，所以查询条件为spuId，暂时不调整
                Spu spu = spuService.getOne(Wrappers.<Spu>lambdaQuery().eq(Spu::getSpuCode, detail.getSpuId()).likeLeft(Spu::getSourceId, Constants.SOURCE_ID_DEFAULT + detail.getSpuId()));
                if (spu == null) {
                    log.error("销售单接收异常,商品为空：{}", str);
//                    throw new UtilException("商品为空");
                    return;
                }
                detail.setSpuId(spu.getId());
                if (saleOrderDetail != null) {
                    detail.setId(saleOrderDetail.getId());
                    saleOrderDetailService.updateById(detail);
                } else {
//                    detail.setStatus(Constants.SALE_ORDER_DETAIL_STATUS_ZERO);
                    saleOrderDetailService.save(detail);
                }
            }
        }
    }

    /**
     * 商品退货，且还未分拣时，不分拣，置退货商品状态为完成
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @param saleOrder
     * @return void
     * @author yw
     * @date 2023-10-31 10:31:48
     */
    public void returnOfGoods(String topic, String tag, String key, String str, SaleOrder saleOrder) {
        SaleOrder saleOrderSale = saleOrderService.getOne(Wrappers.<SaleOrder>lambdaQuery().eq(SaleOrder::getSaleOrderCode, saleOrder.getSaleOrderCode()).eq(SaleOrder::getStatus, com.lvy.hczn.front.common.constant.Constants.SALE_ORDER_STATUS_ZERO));
        if (saleOrderSale != null) {

        }
    }

    /**
     * 送货单转换，wms先做，懒得去改wms单据，按照以前单据方式走
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-06-03 20:33:34
     */
    public void initWarehouseOrder(String topic, String tag, String key, String str) {
        log.error("initWarehouseOrder送货单转换：{}", str);
        ParamInfo<PurchaseOrder> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        PurchaseOrder purchaseOrder = JSONUtil.toBean(JSONUtil.toJsonStr(paramInfo.getData()), PurchaseOrder.class);
        PurchaseOrder purchase = purchaseOrderService.getOne(Wrappers.<PurchaseOrder>lambdaQuery().eq(PurchaseOrder::getPurchaseOrderCode, purchaseOrder.getPurchaseOrderCode()).eq(PurchaseOrder::getSourceId, purchaseOrder.getSourceId()).last("limit 1"));
        if (purchase != null) {
            purchaseOrder.setId(purchase.getId());
            purchaseOrderService.updateById(purchaseOrder);
        } else {
            purchaseOrderService.save(purchaseOrder);
        }
        if (purchaseOrder.getList() != null && !purchaseOrder.getList().isEmpty()) {
            for (PurchaseOrderDetail item : purchaseOrder.getList()) {
                //sourceId为PurchaseOrder的sourceId+传过来的PurchaseOrderDetail的主键
                PurchaseOrderDetail detail = purchaseOrderDetailService.getOne(Wrappers.<PurchaseOrderDetail>lambdaQuery().eq(PurchaseOrderDetail::getPurchaseOrderCode, purchaseOrder.getPurchaseOrderCode()).eq(PurchaseOrderDetail::getSourceId, item.getSourceId()).last("limit 1"));
                //在数据中心取值的时候，spuId赋值为spuCode，所以查询条件为spuId，暂时不调整
                Spu spu = spuService.getOne(Wrappers.<Spu>lambdaQuery().eq(Spu::getSpuCode, item.getSpuId()).likeLeft(Spu::getSourceId, Constants.SOURCE_ID_DEFAULT + item.getSpuId()));
                if (spu == null) {
                    log.error("配送单接收异常，商品为空:{}", str);
                    throw new UtilException("商品为空");
                }
                item.setSpuId(spu.getId());
                if (detail != null) {
                    item.setId(detail.getId());
                    purchaseOrderDetailService.updateById(item);
                } else {
                    purchaseOrderDetailService.save(item);
                }
            }
        }
        System.out.println(purchaseOrder.toString());
    }

    /**
     * 根据平台的货箱租赁但生成门禁
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-05-25 17:11:10
     */
    public void boxLeaseAccess(String topic, String tag, String key, String str) {
        //货箱租赁单生成门禁
        ParamInfo<AccessManager> info = JSONUtil.toBean(str, ParamInfo.class);
        if (info != null && info.getData() != null) {
            AccessManager manager = JSONUtil.toBean(JSONUtil.toJsonStr(info.getData()), AccessManager.class);
            if (!StrUtil.isEmpty(manager.getSourceCode())) {
                if (StrUtil.isEmpty(manager.getAccessCode())) {
                    manager.setAccessCode(manager.getSourceCode());
                }
                AccessManager accessManager = accessManagerService.getOne(Wrappers.<AccessManager>lambdaQuery().eq(AccessManager::getSourceCode, manager.getSourceCode()).last("limit 1"));
                if (accessManager != null) {
                    manager.setId(accessManager.getId());
                    accessManagerService.updateById(manager);
                } else {
                    accessManagerService.save(manager);
                }
            }
        }
    }

    /**
     * 平台修改仓库信息，本地仓库更新
     *
     * @param topic
     * @param tag
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-05-25 17:08:18
     */
    public void updateWarehouse(String topic, String tag, String key, String str) {
        ParamInfo<Warehouse> info = JSONUtil.toBean(str, ParamInfo.class);
        if (info != null && info.getData() != null) {
            Warehouse warehouse = JSONUtil.toBean(JSONUtil.toJsonStr(info.getData()), Warehouse.class);
            warehouseService.updateById(warehouse);
        }
    }

    /**
     * 数据字典同步
     *
     * @param topic
     * @param tga
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-05-22 18:16:23
     */
    public void syncDict(String topic, String tga, String key, String str) {
        SysDictTypeDto sysDictTypeDto = JSONUtil.toBean(str, SysDictTypeDto.class);
        if (sysDictTypeDto.isTypeOfDictData()) {
            if (sysDictTypeDto.getList() != null) {
                SysDictData sysDictData = new SysDictData();
                sysDictData.setDictType(sysDictTypeDto.getDictType());
                sysDictData.setStatus("0");
                sysDictTypeDto.getList().forEach(item -> {
                    try {
                        sysDictData.setDictLabel(item.getDictLabel());
                        List<SysDictData> list = sysDictDataMapper.selectDictDataList(sysDictData);
                        if (!list.isEmpty()) {
                            SysDictData dictData = list.get(0);
                            item.setDictCode(dictData.getDictCode());
                            sysDictDataMapper.updateDictData(item);
                        } else {
                            sysDictDataMapper.insertDictData(item);
                        }
                    } catch (Exception e) {
                        throw new UtilException(e);
                    }
                });
                List<SysDictData> list = sysDictDataMapper.selectDictDataList(sysDictData);
                if (!list.isEmpty()) {
                    DictUtils.setDictCache(sysDictTypeDto.getDictType(), list);
                }
            }
        } else {
            try {
                SysDictType sysDictType = sysDictTypeMapper.selectDictTypeByType(sysDictTypeDto.getDictType());
                if (sysDictType != null) {
                    sysDictTypeDto.setDictId(sysDictType.getDictId());
                    sysDictTypeMapper.updateDictType(sysDictTypeDto);
                } else {
                    sysDictTypeMapper.insertDictType(sysDictTypeDto);
                }
            } catch (Exception e) {
                throw new UtilException(e);
            }
        }
    }

    /**
     * 分类同步
     *
     * @param topic
     * @param tga
     * @param key
     * @param str
     * @return void
     * @author yw
     * @date 2023-05-22 15:28:56
     */
    public void syncCategory(String topic, String tga, String key, String str) {
        log.error("分类同步:{}", str);
        ParamInfo<Category> paramInfo = JSONUtil.toBean(str, ParamInfo.class);
        if (paramInfo != null) {
            if (paramInfo.getData() != null) {
                Category category = JSONUtil.toBean(JSONUtil.toJsonStr(paramInfo.getData()), Category.class);
                categoryService.saveOrUpdate(category);
            } else if (paramInfo.getList() != null && !paramInfo.getList().isEmpty()) {
                List<Category> list = JSONUtil.toList(JSONUtil.toJsonStr(paramInfo.getList()), Category.class);
                list.forEach(item -> {
                    categoryService.saveOrUpdate(item);
                });
            }
        }
    }

    /**
     * 商品同步
     *
     * @param str
     * @param message
     * @return void
     * @author yw
     * @date 2023-05-04 15:13:25
     */
    public void syncSpu(String str, MessageExt message) {
        log.error("商品同步:{}", str);
        ParamInfo<Spu> paramInfo = JSON.parseObject(str, ParamInfo.class);
        if (paramInfo.getList() != null && !paramInfo.getList().isEmpty()) {
            List<Spu> list = JSON.parseArray(JSON.toJSONString(paramInfo.getList()), Spu.class);
            list.forEach(item -> {
                Spu spuInfo = JSON.parseObject(JSON.toJSONString(item), Spu.class);
                saveOrUpdateSpu(spuInfo);
            });
        } else if (paramInfo.getData() != null) {
            Spu spuInfo = JSON.parseObject(JSON.toJSONString(paramInfo.getData()), Spu.class);
            saveOrUpdateSpu(spuInfo);
        }
    }

    private void saveOrUpdateSpu(Spu spuInfo) {
        Spu spu = spuService.saveOrUpdateSpu(spuInfo);
        if (spuInfo.getList() != null && !spuInfo.getList().isEmpty()) {
            spuInfo.getList().forEach(item -> {
                item.setSpuId(spu.getId());
                item.setId(item.getBarcodeId());
                skuService.saveOrUpdateSku(item);
            });
        }
    }

    /**
     * 温区配置同步
     *
     * @param topic
     * @param tga
     * @param key
     * @param str
     */
    public void syncTemperatureZone(String topic, String tga, String key, String str) {
        log.error("温区配置同步:{}", str);
        ParamInfo<TemperatureZone> paramInfo = JSON.parseObject(str, ParamInfo.class);
        if (paramInfo != null && paramInfo.getData() != null) {
            TemperatureZone temperatureZone = JSON.parseObject(JSONUtil.toJsonStr(paramInfo.getData()), TemperatureZone.class);
            temperatureZoneService.saveOrUpdate(temperatureZone);
            if (temperatureZone.getStatus() != null && temperatureZone.getStatus() < 0) {
                temperatureZoneService.removeById(temperatureZone.getId());
            }
        }
    }

    public void syncParcel(String topic, String tga, String key, String str) {
        log.error("包裹信息同步:{}", str);

        TypeReference<ParamInfo<ParcelDataDto>> reference = new TypeReference<>() {
        };

        ParamInfo<ParcelDataDto> paramInfo = JSONUtil.toBean(str, reference, true);
        if (paramInfo != null && paramInfo.getData() != null) {
            ParcelDataDto parcelDataDto = paramInfo.getData();

//            Parcel parcel = parcelDataDto.getParcel();

//            var spu = spuService.getOne(Wrappers.<Spu>lambdaQuery().eq(Spu::getSpuCode,parcel.getParcelNo()));
//            if(ObjUtil.isNotNull(spu)){
//                var skuList = skuService.list(Wrappers.<Sku>lambdaQuery().eq(Sku::getSpuId,spu.getId()));
//                if(CollUtil.isNotEmpty(skuList)){
//                    for (Sku sku : skuList) {
//                        skuService.removeById(sku.getId());
//                    }
//                }
//                spuService.deleteSpuById(spu.getId());
//            }

            spuService.saveOrUpdateSpu(parcelDataDto.getSpu());
            skuService.saveOrUpdateSku(parcelDataDto.getSku());
            parcelService.saveOrUpdate(parcelDataDto.getParcel());
        }
    }
}
